﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace Region
{

    public partial class TreeComboBox : UserControl
    {
        class TreeComboBoxComparer : IComparer
        {
            Dictionary<Object, Item> m_Items;
            public TreeComboBoxComparer(Dictionary<Object, Item> Items) { m_Items = Items; }
            int IComparer.Compare(Object x, Object y)
            {
                return ((new CaseInsensitiveComparer()).Compare(m_Items[x].ToString(), m_Items[y].ToString()));
            }
        }

    
        public event EventHandler ItemChange;
        struct Item
        {
            public Object ParentID;
            public Object ID;
            public String Caption;
            public Int32 Level;
            public TreeNode Node;
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
            public override bool Equals(object obj)
            {
                if (!(obj is Item)) return false;
                Item i = (Item)obj;
                if (i.ID != ID) return false;
                return true;                
            }
            public override String ToString()
            {
                //return new string(' ', Level*2) + Caption;
                return Caption;
            }
        }
        //Form m_DropDown;
        ToolStripDropDownButton dropDownButton1;
        ToolStripDropDown dropDown;
        TreeView m_TV;
        Object m_SelectItemID;
        private Dictionary<Object, Item> m_Items;
        private Dictionary<Object, List<Object>> m_Parent;
        public Object SelectItemID() 
        {
            return m_SelectItemID;
            //if (comboBox1.SelectedItem == null) return null; else return ((Item)comboBox1.SelectedItem).ID; 
            
        }
        public Object SelectItemID(Object ID) 
        {
            if (m_Items.ContainsKey(ID))
            {
                dropDownButton1.Text = m_Items[ID].Caption;
                m_SelectItemID = ID;
                m_TV.SelectedNode = m_Items[ID].Node;
                if (ItemChange != null) ItemChange(this, EventArgs.Empty); 

            }
            return m_SelectItemID;
            //comboBox1.SelectedItem = m_Items[ID]; if (comboBox1.SelectedItem == null) return null; else return ((Item)comboBox1.SelectedItem).ID;             
        }
        public void Add(Object ParentID, Object ID, String Caption)
        {
            Item i = new Item();
            i.ParentID = ParentID;
            i.ID = ID;
            i.Caption = Caption;
            m_Items[i.ID]= i;
        }
        public void Clear()
        {
            m_SelectItemID = null;
            m_Items = new Dictionary<Object, Item>();
            m_Parent = null;       
            m_TV.Nodes.Clear();
        }
        void ShowTreeListItem(Object ID,Int32 Level)
        {            
            if (m_Items.ContainsKey(ID))
            {
                Item i = m_Items[ID];
                i.Level = Level;
                //comboBox1.Items.Add(i);
                if (i.Node == null)
                {
                    i.Node = new  TreeNode(i.Caption);
                    i.Node.Tag = i;
                    if (m_Items.ContainsKey(i.ParentID))
                        m_Items[i.ParentID].Node.Nodes.Add(i.Node);
                    else
                        m_TV.Nodes.Add(i.Node);
                    m_Items[ID] = i;
                }
                
            };
            if (m_Parent.ContainsKey(ID))
            {
                ArrayList L = new ArrayList();
                foreach (Object ID1 in m_Parent[ID]) L.Add(ID1);
                L.Sort(new TreeComboBoxComparer(m_Items));
                foreach (Object ID1 in L) ShowTreeListItem(ID1, Level + 1);
            }
        }
        public void ShowTreeList()
        {
            List<Object> Root = new List<Object>();
            m_Parent = new Dictionary<Object, List<Object>>();
            foreach (KeyValuePair<Object,Item> Param in m_Items)
            {
                Item  i = (Item)Param.Value;
                if (!m_Parent.ContainsKey(i.ParentID)) m_Parent[i.ParentID] = new List<Object>();
                m_Parent[i.ParentID].Add(i.ID);
            }
            foreach (KeyValuePair<Object, List<Object>> Param in m_Parent)
                if (!m_Items.ContainsKey(Param.Key))
                    Root.Add(Param.Key);
            //comboBox1.Items.Clear();
            foreach (Object r in Root)
                ShowTreeListItem(r, 0);
        }
        public TreeComboBox()
        {
            m_SelectItemID = null;
            m_Items = new Dictionary<Object, Item>();
            InitializeComponent();
            dropDownButton1 = new ToolStripDropDownButton();
            dropDown = new ToolStripDropDown();
            dropDown.AutoSize = true;
            //dropDown.Width = 200;
            //dropDown.Height = 200;            
            dropDownButton1.DropDown = dropDown;
            dropDownButton1.Text = "";
            dropDownButton1.TextAlign = ContentAlignment.MiddleLeft;
            dropDownButton1.AutoSize = false;
            //dropDownButton1.Width = 200;            
            // Set the drop-down direction.
            dropDownButton1.DropDownDirection = ToolStripDropDownDirection.Default;
            //dropDown.Items.AddRange(new ToolStripItem[] { new ToolStripControlHost(TV) });
            toolStrip1.Items.Add(dropDownButton1);

            //comboBox1.DropDownHeight = 1;

            //comboBox1.DropDownWidth = 1;
            //m_DropDown = new Form();
            m_TV = new TreeView();
            /*m_DropDown.FormBorderStyle = FormBorderStyle.None;            
            m_DropDown.Controls.Add(m_TV);
            m_DropDown.Select();*/
            m_TV.Location = new Point(0, 0);
            m_TV.Size = new Size(300, 200);
            m_TV.Dock = DockStyle.Fill;
            m_TV.Visible = true;
            m_TV.LostFocus += TV_LostFocus;
            m_TV.AfterSelect += TV_AfterSelect;
            m_TV.Select();
            dropDown.Items.AddRange(new ToolStripItem[] { new ToolStripControlHost(m_TV) });
            /*m_DropDown.ResumeLayout(false);*/
            TreeComboBox_Resize(this, null);
        }
        private void TV_AfterSelect(System.Object sender,
        System.Windows.Forms.TreeViewEventArgs e)
        {
            Item i = (Item)e.Node.Tag;
            SelectItemID(i.ID);
            //comboBox1.SelectedItem = i;
        }
        private void comboBox1_DropDown(object sender, EventArgs e)
        {
            /*this.Left = this.Left;
            Point P = this.PointToScreen(new Point(0, this.Height));            
            m_DropDown.Show();
            m_DropDown.Left = P.X;
            m_DropDown.Top = P.Y;
            m_TV.Focus();
            m_DropDown.Activate();            */
        }
        private void TV_LostFocus(object sender, EventArgs e)
        {
            //m_DropDown.Hide();
            Item i = (Item)m_TV.SelectedNode.Tag;
            //comboBox1.SelectedItem = i;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void TreeComboBox_Resize(object sender, EventArgs e)
        {
            if (dropDownButton1!=null) 
            {
                toolStrip1.Width = Width;
                toolStrip1.Height = Height;
                dropDownButton1.Width = Width-1 ;
                dropDownButton1.Height = Height-1 ;
                m_TV.Width = Width - 1;
            }
        }
    }
}
